package handler

import (
	"sync"

	"fmt"
	example "git.oschina.net/wkc/master-key-go/proto/example"
	"github.com/mgutz/logxi/v1"
	"github.com/micro/go-micro/errors"
	"golang.org/x/net/context"
)

type KeyMq struct {
	agents map[string]chan example.SendRequest
	mux    sync.Mutex
}

func New() *KeyMq {
	return &KeyMq{
		agents: make(map[string]chan example.SendRequest),
	}
}

const ErrIDSend = "go.micro.srv.master-key-go.KeyMq.Send"
const ErrIDListen = "go.micro.srv.master-key-go.KeyMq.Listen"

func (e *KeyMq) Listen(ctx context.Context, req *example.ListenRequest, stream example.KeyMq_ListenStream) error {
	log.Info("Received KeyMq.Listen request", "req", req)
	if req.Id == "" {
		return errors.BadRequest(ErrIDSend, "id should not empty")
	}
	e.mux.Lock()
	ch := make(chan example.SendRequest)
	e.agents[req.Id] = ch
	e.mux.Unlock()

	for {
		msg := <-ch
		err := stream.Send(&example.ListenResponse{
			Op: msg.Op,
		})
		if err != nil {
			log.Error("stream.Send", "err", err)
			e.mux.Lock()
			delete(e.agents, req.Id)
			e.mux.Unlock()
			break
		}
	}
	return nil
}

func (e *KeyMq) Send(ctx context.Context, req *example.SendRequest, rsp *example.SendResponse) error {
	log.Info("Received KeyMq.Send request", "req", req)
	if req.Id == "" {
		return errors.BadRequest(ErrIDSend, "id should not empty")
	}
	if req.Op == nil {
		return errors.BadRequest(ErrIDSend, "op should not empty")
	}
	switch req.Op.Type {
	case "KeyTap":
		break
	case "TypeString":
		break
	default:
		return errors.BadRequest(ErrIDSend, `op.type support "KeyTap", "TypeString"`)
	}
	e.mux.Lock()
	defer e.mux.Unlock()
	v, ok := e.agents[req.Id]
	if !ok {
		return errors.BadRequest(ErrIDSend, "Agents not exists")
	}
	v <- *req
	return nil
}

func (e *KeyMq) Version(ctx context.Context, req *example.VersionRequest, rsp *example.VersionResponse) error {
	log.Info("Received KeyMq.Version request", "req", req)
	if req.Version == "" {
		req.Version = "未知版本"
	}
	if req.Version != "20170326-dev-2" {
		rsp.Version = "20170326-dev-2"
		rsp.IsOutdate = true
		rsp.Message = fmt.Sprintf("你的当前版本 %q, 最新版本 %q，请访问 https://master-key.hi-hi.cn/ 下载最新版本", req.Version, rsp.Version)
	}
	return nil
}
